iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
0

很多代碼會用boolean當作回傳的成功或失敗,例如:我們使用者的訂單儲存到資料庫時,我們會想知道這個動作最後有沒有成功。

public interface IOrderRepository
{
    bool Save(Order order);
}

或者是當SaveOrder需要告訴外部更多資訊時,我們也常搭配Enum使用錯誤碼來表示狀態,例如:訂單成功時回傳Success、訂單還在等待接受時回傳Waiting、訂單被拒絕時回傳Rejected。

public enum OrderStatus
{
    Success,
    Waiting,
    Rejected
}

public interface IOrderRepository
{
    OrderStatus Save(Order order);
}

public class OrderService
{
		private readonly IOrderRepository _orderRepository;

    ...
    
    public OrderStatus Save(Order order)
    {
        return _orderRepository.Save(order);
    }
}

TransactionService就會拿到OrderStatus後判斷,並把錢退回給使用者。

public class TransactionService
{
    private readonly OrderService _orderService;

    ...
    
    public OrderStatus Save(int userId, int goodsId)
    {
        var order = new Order(GetUser(userId), GetGoods(goodsId));
        var status = _orderService.Save(order);
        if (status == OrderStatus.Rejected)
        {
            Refund(order);
        }
        return status;
    }
}

這樣的設計容易造成一些問題,假設今天Refundu也會回傳狀態來表示其成功或失敗。

public class TransactionService
{
    private readonly OrderService _orderService;

    ...
    
    public OrderStatus Save(int userId, int goodsId)
    {
        var order = new Order(GetUser(userId), GetGoods(goodsId));
        var status = _orderService.Save(order);
        if (status == OrderStatus.Rejected)
        {
            Refund(order);
						if (isSuccess)
		        {
		            return status;
		        }

			      return OrderStatus.Rejected;
        }
        return status;
    }
}

就會被OrderStatus的回傳值限制,因為回傳值必須是OrderStatus,所以導致Refund的結果必須在Save中判斷處理。

另一種情況是當有其他類別使用到OrderServer.Save時,很容易也會需要把status繼續往外傳,讓更外面的類別可以根據status中的某一個狀態做處理。例如:

public class TransactionController
{
    ...
    
    public IActionResult Confirm(int userId, int goodsId)
    {
        var orderStatus = _transactionService.Save(userId, goodsId);
        if (orderStatus == OrderStatus.Success)
        {
            return Ok();
        }
        return BadRequest();
    }
}

下訂單成功的時候,我們通常不會需要特別處理,直到UI要把成功訊息顯示到使用者面前,或者是Api要回傳response時,我們才會判斷狀態是否成功。為了傳遞OrderStatus,中間所有類別的所有回傳值都被限制成OrderStatus。

今天的問題稍微有點複雜,我們稍微整理一下回傳boolean或錯誤碼帶來的問題

  1. 當方法中有有其他異常流程需要處理時,會需要更多判斷來控制流程,讓最後結果只有一個錯誤碼
  2. 如果從UI到底層都需要處理錯誤碼,中間流程的回傳值就容易被限制。

我們明天會繼續聊到該怎麼更有效地處理這種狀況。


上一篇
Day 15 兩個集合的比較
下一篇
Day 17 當錯誤發生時(下)
系列文
在Kata中尋找Clean Code是否搞錯了什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言